"""
网络请求工具模块
"""
import urllib.parse
import requests
import time
import random
import json
from typing import Dict, Any, Optional
from config.settings import HEADERS, COOKIES, REQUEST_PARAMS_TEMPLATE, API_ENDPOINTS
from utils.logger import logger


class NetworkClient:
    """网络请求客户端"""
    
    def __init__(self, debug: bool = False, user_id: str = None):
        self.session = requests.Session()
        self.session.headers.update(HEADERS)
        self.session.cookies.update(COOKIES)
        self.debug = debug
        self.user_id = user_id or 'default'
        
        # 为不同用户设置不同的User-Agent（避免被识别为同一用户）
        if user_id and user_id != 'default':
            # 在User-Agent中添加用户标识
            original_ua = self.session.headers.get('user-agent', '')
            self.session.headers['user-agent'] = f"{original_ua} User-{user_id}"
    
    def encode_string(self, text: str) -> str:
        """编码字符串"""
        return urllib.parse.quote(text)
    
    def _log_request(self, method: str, url: str, params: Dict = None, data: str = None, headers: Dict = None):
        """记录请求信息"""
        if not self.debug:
            return
            
        logger.log(f"=== 网络请求 DEBUG (用户: {self.user_id}) ===", "network")
        logger.log(f"方法: {method}", "network")
        logger.log(f"URL: {url}", "network")
        
        if params:
            logger.log(f"请求参数: {json.dumps(params, indent=2, ensure_ascii=False)}", "network")
        
        if data:
            # 格式化POST数据
            formatted_data = self._format_post_data(data)
            logger.log(f"POST数据: {formatted_data}", "network")
        
        if headers:
            logger.log(f"请求头: {json.dumps(headers, indent=2, ensure_ascii=False)}", "network")
    
    def _log_response(self, response: requests.Response):
        """记录响应信息"""
        if not self.debug:
            return
            
        logger.log(f"=== 响应信息 DEBUG (用户: {self.user_id}) ===", "network")
        logger.log(f"状态码: {response.status_code}", "network")
        logger.log(f"响应头: {dict(response.headers)}", "network")
        
        try:
            if response.headers.get('content-type', '').startswith('application/json'):
                response_data = response.json()
                logger.log(f"响应内容: {json.dumps(response_data, indent=2, ensure_ascii=False)}", "network")
            else:
                logger.log(f"响应内容: {response.text[:500]}...", "network")
        except Exception as e:
            logger.log(f"解析响应失败: {e}", "network")
            logger.log(f"原始响应: {response.text[:500]}...", "network")
    
    def _format_post_data(self, data: str) -> str:
        """格式化POST数据以便阅读"""
        try:
            # 解析URL编码的数据
            parsed_data = urllib.parse.parse_qs(data)
            formatted = {}
            for key, values in parsed_data.items():
                if len(values) == 1:
                    formatted[key] = values[0]
                else:
                    formatted[key] = values
            
            return json.dumps(formatted, indent=2, ensure_ascii=False)
        except Exception:
            return data[:500] + "..." if len(data) > 500 else data

    def get_timeslots(self, service_id: str, duration: int, date: str, 
                     use_range_search: bool = True, calendar_id: str = None) -> Optional[Dict]:
        """获取时间段信息"""
        try:
            params = REQUEST_PARAMS_TEMPLATE.copy()
            params.update({
                'serviceid': service_id,
                'duration': str(duration),
                'date': date
            })
            
            # 如果提供了calendar_id，则设置该参数
            if calendar_id:
                params['calendarid'] = calendar_id
            
            # 根据curl请求，不使用rangesearch参数
            # if use_range_search:
            #     params['rangesearch'] = '1'
            
            # 记录请求信息
            self._log_request('GET', API_ENDPOINTS['timeslots'], params=params)
            
            response = self.session.get(
                API_ENDPOINTS['timeslots'],
                params=params,
                timeout=30
            )
            
            # 记录响应信息
            self._log_response(response)
            
            if response.status_code == 200:
                return response.json()
            else:
                logger.log(f"获取时间段请求失败: {response.status_code}", "network")
                return None
                
        except Exception as e:
            logger.log(f"获取时间段异常: {e}", "network")
            return None
    
    def book_appointment(self, booking_data: str) -> Optional[Dict]:
        """预约时间段"""
        try:
            # 记录请求信息
            self._log_request('POST', API_ENDPOINTS['appointment'], data=booking_data)
            
            response = self.session.post(
                API_ENDPOINTS['appointment'],
                data=booking_data,
                timeout=30
            )
            
            # 记录响应信息
            self._log_response(response)
            
            if response.status_code == 200:
                return response.json()
            else:
                logger.log(f"预约请求失败: {response.status_code}", "network")
                return None
                
        except Exception as e:
            logger.log(f"预约请求异常: {e}", "network")
            return None
    
    def add_delay(self, min_delay: int = 1, max_delay: int = 5):
        """添加随机延迟"""
        delay = random.randint(min_delay, max_delay)
        time.sleep(delay)
    
    def set_debug(self, debug: bool):
        """设置debug模式"""
        self.debug = debug
        logger.log(f"网络请求debug模式: {'开启' if debug else '关闭'}", "network")
    
    def get_session_info(self):
        """获取当前session信息"""
        return {
            'headers': dict(self.session.headers),
            'cookies': dict(self.session.cookies),
            'debug': self.debug
        }


# 全局网络客户端实例（默认关闭debug）
network_client = NetworkClient(debug=False)
